﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;

namespace Dario
{
    static class Extension {
        public static Nodo GetMin(this List<Nodo> src ) {
            foreach (var nodo in src.Where(nodo => !nodo.Scelto)) {
                nodo.Scelto = true;
                return nodo;
            }
            return null;
        }

        public static Nodo GetByName(this List<Nodo> src, int id) {
            return src.FirstOrDefault(nodo => nodo.Nome == id);
        }

        public static int FirstLibero(this List<int> src, List<Nodo> pers) {
            return src.FirstOrDefault(i => !pers.GetByName(i).Scelto);
        }
    }

    class Program {
        private readonly List<List<Coppia>> _ris = new List<List<Coppia>>();
        readonly List<Nodo> _persone = new List<Nodo>();
        private const int N = 16;

        static void Main(string[] args) {
            
            var p = new Program();
            p.Inizializza();
            for (var i = 1; i < N; i++) {
                p.InizializzaGiornata();
                p._ris.Add(new List<Coppia>());
                for (var j = 0; j < N/2; j++) {
                    var pers = p._persone.GetMin();
                    var compare = pers.GetMin(p._persone);
                    var comp = p._persone.GetByName(compare) ?? new Nodo(0, N);
                    comp.Scelto = true;
                    p._ris.Last().Add(new Coppia(pers,comp));
                    Console.WriteLine(pers.Nome + " " + comp.Nome);
                    

                }
                Console.WriteLine();
            }
            Console.ReadLine();

            try
            {

                //Pass the filepath and filename to the StreamWriter Constructor
                var sw = new StreamWriter("D:\\Test123.txt");
                var i = 0;
                foreach (var coppia in p._ris)
                {
                    sw.WriteLine("Giornata {0}",++i);
                    foreach (var rigo in coppia)
                        sw.WriteLine("|"+rigo.I.Nome + "| |" + rigo.J.Nome+"|");
                    sw.WriteLine();
                }

               
                sw.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception: " + e.Message);
            }
            finally
            {
                Console.WriteLine("Executing finally block.");
            }
            Console.ReadLine();

        }
        void Inizializza()
        {
            for (var i = 1; i <= N; i++)
                _persone.Add(new Nodo(i,N));
        }

        void InizializzaGiornata()
        {
            foreach (var nodo in _persone)
                nodo.Scelto = false;           
        }
    }


    class Coppia {
        public Nodo I, J;
        public Coppia(Nodo n, Nodo m)
        {
            I = n;
            J = m;
        }
        
    }

    class Nodo {
        public int Nome { get; private set; }
        private readonly List<int> _liberi;
        private readonly int _tot;
        public bool Scelto;
        public Nodo(int nome, int t) {
            Nome = nome;
            _tot = t;
            _liberi = Init(nome);
        }

        private List<int> Init(int nome) {
            var temp = new List<int>();
            for (var i = nome+1; i <= _tot; i++) {
                if(i!= nome)
                    temp.Add(i);
            }
            return temp;
        }

        void Remove(int togli) {
            _liberi.Remove(togli);
        }
        public int GetMin(List<Nodo> pers ) {
            var a = _liberi.FirstLibero(pers);
            Remove(a);
            return a;
        }

    }
}
